package online.yangcloud.web.service;

import cn.hutool.json.JSONObject;
import online.yangcloud.common.enumration.FileExtTypeEnum;
import online.yangcloud.common.model.view.PagerView;
import online.yangcloud.core.model.entity.UserEntity;
import online.yangcloud.core.model.request.file.DirLooker;
import online.yangcloud.core.model.request.file.FileSearcher;
import online.yangcloud.core.model.request.file.TrashQuery;
import online.yangcloud.core.model.view.file.BreadsView;
import online.yangcloud.core.model.view.file.FileMetadataView;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author zhuboyang
 * @since 2023年05月17 10:47:13
 */
public interface FileService {

    /**
     * 初始化用户的文件根目录
     *
     * @param userId 用户 id
     */
    void initialUserRoot(String userId);

    /**
     * 新建文件夹
     *
     * @param pid    父级文件 id
     * @param name   文件夹名
     * @param userId 当前登录用户 id
     * @return 文件夹元数据
     */
    FileMetadataView mkdir(String pid, String name, String userId);

    /**
     * 批量删除文件及文件夹
     *
     * @param ids  文件或文件夹 id 列表
     * @param user 当前登录用户
     */
    void batchDeleteFile(List<String> ids, UserEntity user);

    /**
     * 批量复制文件
     *
     * @param sourcesIds 待复制文件列表
     * @param targetId   目标目录
     * @param user       当前登录用户
     */
    void batchCopy(List<String> sourcesIds, String targetId, UserEntity user);

    /**
     * 批量复制文件
     *
     * @param sourcesIds 待复制文件列表
     * @param targetId   目标目录
     * @param userId     当前登录用户 id
     */
    void batchMove(List<String> sourcesIds, String targetId, String userId);

    /**
     * 恢复已删除的文件及文件夹
     * 但不会恢复到原来位置，会恢复到账户根目录下
     *
     * @param idsList 要恢复的文件及文件夹 id 列表
     * @param user    文件归属人
     */
    void rollbackTrash(List<String> idsList, UserEntity user);

    /**
     * 修改文件名
     *
     * @param id   文件 id
     * @param name 文件名
     */
    void rename(String id, String name);

    /**
     * 查询文件元数据
     *
     * @param id     文件 id
     * @param userId 用户 id
     * @return 文件元数据
     */
    FileMetadataView queryById(String id, String userId);

    /**
     * 查询面包屑导航数据
     *
     * @param id     当前所在目录的文件 id
     * @param userId 当前登录的用户 id
     * @return 面包屑导航数据
     */
    List<BreadsView> queryBreads(String id, String userId);

    /**
     * 分段查询已删除的文件
     *
     * @param query  查询条件
     * @param userId 文件所属用户 id
     * @return 文件列表
     */
    PagerView<FileMetadataView> queryDeletedFiles(TrashQuery query, String userId);

    /**
     * 分页搜索某一目录下次一层级的所有文件及文件夹
     *
     * @param searcher 分页参数
     * @param userId   当前登录的用户 id
     * @return 次一层级的所有文件及文件夹列表
     */
    PagerView<FileMetadataView> queryFiles(FileSearcher searcher, String userId);

    /**
     * 查询目录下所有的文件夹
     *
     * @param looker 查询参数
     * @param userId 当前登录的用户 id
     * @return 文件夹列表
     */
    List<FileMetadataView> queryDirs(DirLooker looker, String userId);

    /**
     * 计算文件名后缀数字（检查是否有重复的文件名）
     *
     * @param pid      父级目录 id
     * @param name     文件名
     * @param fileType 文件类型
     * @return 计算出的文件名后缀数字
     */
    Integer calculateSuffixNumber(String pid, String name, Integer fileType);

    /**
     * 计算文件名（检查是否有重复的文件名，如果有，就在文件名后添加后缀数字）
     *
     * @param pid      父级目录 id
     * @param name     文件名
     * @param fileType 文件类型
     * @return 计算后的文件名
     */
    String calculateName(String pid, String name, Integer fileType);

    /**
     * 检测是否有重复的文件名称
     *
     * @param id       文件 id
     * @param pid      父级目录 id
     * @param name     文件名
     * @param fileType 文件类型
     * @return 检测结果
     */
    Boolean validDuplicatedName(String id, String pid, String name, Integer fileType);

    /**
     * 将视频片段合并为完整的视频，并存放至临时文件夹中
     *
     * @param id     视频 id
     * @param userId 文件所属人
     * @return 文件元数据
     */
    FileMetadataView combineToTmp(String id, String userId);

    /**
     * 查询指定目录下所有的文件
     *
     * @param pid     目录的文件 id
     * @param userId  文件所属人
     * @param extType 文件类型
     * @return 文件列表
     */
    List<FileMetadataView> queryFilesUnderDir(String pid, String userId, FileExtTypeEnum extType);

    /**
     * 批量查询文件扩展信息
     *
     * @param fileId 文件 id
     * @param ext    文件后缀
     * @return 文件扩展信息
     */
    JSONObject queryFileExtend(String fileId, FileExtTypeEnum ext);

    /**
     * 文件下载
     *
     * @param id       文件 id
     * @param response 响应
     */
    void download(String id, HttpServletResponse response);

}
